package org.example.methodreference;

import com.alibaba.fastjson.JSONObject;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;

public class Java8MethodReference3b {
    public static void main(String[] args) {
        Invoice obj = new Invoice("A001", BigDecimal.valueOf(1.99), 3);
        InvoiceCalculator formula = new InvoiceCalculator();
        BigDecimal result = calculator(formula, obj, (invoiceCalculator, invoice) -> invoiceCalculator.normal(invoice));
        System.err.println(result);
        BigDecimal result1 = calculator(formula,obj,InvoiceCalculator::normal);
        System.err.println(result1);
        BigDecimal result2 = calculator(formula,obj,(f,o) -> f.promotion(o));
        System.err.println(result2);
        BigDecimal result3 = calculator(formula,obj,InvoiceCalculator::promotion);
        System.err.println(result3);

        List<BigDecimal> list = Arrays.asList(
                BigDecimal.valueOf(9.99),
                BigDecimal.valueOf(2.99),
                BigDecimal.valueOf(8.99)
        );
        List<Invoice> invoices = fakeInvoice(list,Invoice::new);
        System.err.println(JSONObject.toJSONString(invoices,true));

    }
    static List<Invoice> fakeInvoice(List<BigDecimal> list, Function<BigDecimal,Invoice> function){
        List<Invoice> result = new ArrayList<>();
        for (BigDecimal bigDecimal : list) {
            result.add(function.apply(bigDecimal));
        }
        return result;
    }

    static BigDecimal calculator(InvoiceCalculator formula, Invoice invoice, BiFunction<InvoiceCalculator,Invoice,BigDecimal> func){
        return func.apply(formula,invoice);
    }
}
class InvoiceCalculator{
    public BigDecimal normal(Invoice obj){
        return obj.getUnitPrice().multiply(BigDecimal.valueOf(obj.getQty()));
    }

    public BigDecimal promotion(Invoice obj){
        return obj.getUnitPrice().multiply(BigDecimal.valueOf(obj.getQty()))
                .multiply(BigDecimal.valueOf(0.9))
                .setScale(2, RoundingMode.HALF_UP);
    }
}
class Invoice{
    String no;
    BigDecimal unitPrice;
    Integer qty;

    public Invoice(BigDecimal unitPrice) {
        this.unitPrice = unitPrice;
    }

    public Invoice(String no, BigDecimal unitPrice, Integer qty) {
        this.no = no;
        this.unitPrice = unitPrice;
        this.qty = qty;
    }

    public String getNo() {
        return no;
    }

    public BigDecimal getUnitPrice() {
        return unitPrice;
    }

    public Integer getQty() {
        return qty;
    }
}
